package wineshop.domain.market;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import wineshop.domain.general.Address;
import wineshop.domain.general.Country;

public class SellerTest {
	Seller laVersa;
	Seller torres;
	Product product;
	Address address;

	@Before
	public void setUp() {
		Country italy = new Country("Italy");
		Country spain = new Country("Spain");
		Address addressLaVersa = new Address("Via F.Crispi", "15",
				"Santa Maria della Versa", "27047", italy);
		Address addressTorres = new Address("M. Torres", "6", "Barcelona",
				"08720", spain);
		laVersa = new Seller("La Versa", addressLaVersa);
		torres = new Seller("Torres", addressTorres);
		product = new Product("Spumante", "Italian dessert wine.", "white", 75,
				12.0);
		address = addressTorres;
	}

	@Test
	public void shouldManageItemIfSellerCreatedIt() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);

		Exception e;
		try {
			laVersa.checkIfItemCanBeManaged(wine);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNull(e);

		try {
			torres.checkIfItemCanBeManaged(wine);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNotNull(e);
	}

	@Test
	public void shouldManageItemIfNotSold() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);
		laVersa.changeAvailability(true, wine);
		assertTrue(!wine.isSold());

		Exception e;
		try {
			laVersa.checkIfItemCanBeManaged(wine);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNull(e);

		Customer customer = new Customer("tom", "jones", "tjones");
		laVersa.sell(wine, customer, new Creditcard("123", customer), address);

		assertTrue(wine.isSold());

		try {
			laVersa.checkIfItemCanBeManaged(wine);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNotNull(e);
	}

	@Test
	public void shouldMakeANewItem() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);
		assertNotNull(wine);
	}

	@Test
	public void shouldSellAnOwnedItem() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);
		laVersa.changeAvailability(true, wine);
		Customer customer = new Customer("tom", "jones", "tjones");
		Exception e;
		try {
			laVersa.sell(wine, customer, new Creditcard("123", customer),
					address);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNull(e);
	}

	@Test
	public void shouldSellAnItemNotSold() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);
		laVersa.changeAvailability(true, wine);
		Customer customer = new Customer("tom", "jones", "tjones");

		assertTrue(!wine.isSold());

		Exception e;
		try {
			laVersa.sell(wine, customer, new Creditcard("123", customer),
					address);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNull(e);
	}

	@Test
	public void shouldNotSellASoldItem() {
		Item wine = laVersa.makeNewItem(product, "ABC", 1000, 2006);
		laVersa.changeAvailability(true, wine);
		Customer customer = new Customer("tom", "jones", "tjones");

		assertTrue(!wine.isSold());

		Exception e;
		try {
			laVersa.sell(wine, customer, new Creditcard("123", customer),
					address);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNull(e);

		assertTrue(wine.isSold());

		try {
			laVersa.sell(wine, customer, new Creditcard("123", customer),
					address);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNotNull(e);
	}

	@Test
	public void shouldNotSellANotOwnedItem() {
		Item wine = torres.makeNewItem(product, "ABC", 1000, 2006);
		torres.changeAvailability(true, wine);
		Customer customer = new Customer("tom", "jones", "tjones");

		Exception e;
		try {
			laVersa.sell(wine, customer, new Creditcard("123", customer),
					address);
			e = null;
		} catch (RuntimeException rte) {
			e = rte;
		}
		assertNotNull(e);
	}

	@After
	public void tearDown() {
		laVersa = null;
		torres = null;
		product = null;
		address = null;
	}
}
